/*
 * @Author: zdc 3215400595@qq.com
 * @Date: 2023-08-08 20:15:26
 * @LastEditors: zdc 3215400595@qq.com
 * @LastEditTime: 2023-08-08 21:17:04
 * @FilePath: /Log_system/bench/bench.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "../Logs_System/tonglog.hpp"
#include <vector>
#include <thread>
#include <chrono>
void bench(const std::string &logger_name, size_t thread_count, size_t msg_count, size_t msg_len)
{
    // 1.获取日志器
    tong_log::Logger::ptr logger = tong_log::getLogger(logger_name);
    if (logger.get() == nullptr)
        return;
    std::cout << "测试日志 : " << msg_count << "条，总大小：" << (msg_count * msg_len) / 1024 << "KB\n";
    // 2.组织指定长度日志消息
    std::string msg(msg_len - 1, 'T'); // 少一个字节，为了添加换行
    // 3.创建指定数量的线程
    std::vector<std::thread> threads;
    size_t mes_per_thr = msg_count / thread_count; // 每个线程输出的日志数量，平均分开
    std::vector<double> cost_arry(thread_count);
    for (int i = 0; i < thread_count; i++)
    {
        threads.emplace_back([&, i]()
                             {
                                 // 4.线程函数内部开始计时
                                 auto start = std::chrono::high_resolution_clock::now();
                                 // 5.开始循环写日志
                                 for (size_t j = 0; j < mes_per_thr; j++)
                                 {
                                     logger->fatal("%s", msg.c_str());
                                 }
                                 // 6.线程函数内部结束计时
                                 auto end = std::chrono::high_resolution_clock::now();
                                 auto cost = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
                                cost_arry[i] = cost.count();
                                 std::cout << "线程" << i << " : "
                                           << "\t输出日志数量 : " << mes_per_thr << ",耗时: " << cost.count() << "s" << std::endl; });
    }

    for (int i = 0; i < thread_count; i++)
    {
        threads[i].join();
    }
    // 7.计算总耗时:多线程中，每个线程都会耗时，并发的，耗时最长的就是总时间
    double max_cost = cost_arry[0];
    for (int i = 1; i < thread_count; i++)
        max_cost = max_cost < cost_arry[i] ? cost_arry[i] : max_cost;
    size_t msg_per_sec = msg_count / max_cost;
    size_t size_per_sec = (msg_count * msg_len) / (max_cost * 1024);
    // 8.进行输出打印

    std::cout << "/t总耗时: " << max_cost << "s\n";
    std::cout << "/t平均每秒输出日志数量: " << msg_per_sec << "条\n";
    std::cout << "/t平均每秒输出日志大小: " << size_per_sec << "KB\n";
}
void sysn_bench()
{
    std::unique_ptr<tong_log::LoggerBuilder> builder(new tong_log::GlobalLoggerBulider());
    builder->buildLoggerName("sync_logger");
    builder->buildLoggerFormatter("%m%n");
    builder->buildLoggerType(tong_log::LoggerType::LOGGER_SYNC);
    builder->buildSink<tong_log::FileSink>("./logfile/sync.log");
    builder->buildLoggerLevel(tong_log::LogLevel::value::DEBUG);

    builder->build();

    bench("sync_logger", 3, 1000000, 100);
}
void async_bench()
{
    std::unique_ptr<tong_log::LoggerBuilder> builder(new tong_log::GlobalLoggerBulider());
    builder->buildLoggerName("async_logger");
    builder->buildLoggerFormatter("%m%n");
    builder->buildLoggerType(tong_log::LoggerType::LOGGER_SYNC);

    builder->buildEnableUnsafeAsync(); //开启非安全模式，排除为了将实际落地时间排除在外
     
    builder->buildSink<tong_log::FileSink>("./logfile/async.log");
    builder->buildLoggerLevel(tong_log::LogLevel::value::DEBUG);

    builder->build();

    bench("async_logger", 1, 1000000, 100);
}
int main()
{
    async_bench();
}